package com.shiyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.shiyi.core.vo.Menu;
import com.shiyi.core.vo.Role;
import com.shiyi.core.vo.TokenUser;
import com.shiyi.system.redis.RedisCache;
import com.shiyi.core.utils.StringHelper;
import com.shiyi.core.utils.encryption.EncryptUtils;
import com.shiyi.core.utils.result.Result;
import com.shiyi.system.entity.SysUser;
import com.shiyi.system.mapper.SysUserMapper;
import com.shiyi.system.service.SysMenuService;
import com.shiyi.system.service.SysRoleService;
import com.shiyi.system.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shiyi.system.utils.EntityConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author shiyi
 * @since 2020-11-19
 */
@Service
@Transactional
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

   /* @Override
    public User loadUserByUsername(String userName) {
        return this.baseMapper.loadUserByUsername(userName);
    }*/

    @Override
    public boolean insertUser(SysUser user) {
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        return this.save(user);
    }

    @Override
    public boolean queryUserByUserName(String userName) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        return this.getOne(wrapper) == null;
    }

    @Override
    public SysUser queryUserByName(String userName) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", userName);
        return this.getOne(wrapper);
    }

    @Override
    public boolean queryUserByIdAndName(SysUser user) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", user.getUserName());
        wrapper.ne("id", user.getId());
        return this.getOne(wrapper) == null;
    }

    @Override
    public boolean updateUser(SysUser user) {
        user.setUpdateTime(new Date());
        return this.updateById(user);
    }

    @Override
    public List<SysUser> listUser() {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.select(SysUser.class, tableFieldInfo -> !"password".equals(tableFieldInfo.getColumn()));
        wrapper.eq("is_delete", 0);
        return this.list(wrapper);
    }

    @Override
    public boolean deleteUser(String id) {
        UpdateWrapper<SysUser> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", id);
        wrapper.set("update_time", new Date());
        wrapper.set("is_delete", 2);
        return this.update(wrapper);
    }

    @Override
    public Result<Object> userLogin(String username, String password) {
        TokenUser sysUser = this.baseMapper.queryUserByUserName(username);
        if (sysUser == null) {
            return Result.fail(EntityConstant.USERNAME_NOT_EXIST);
        }
        if (!EncryptUtils.MD5(password).equals(sysUser.getPassword())) {
            return Result.fail(EntityConstant.PASSWORD_INCORRECT);
        }
        // 查询角色信息
        List<Role> roles = sysRoleService.queryRolesByUserId(sysUser.getId());
        sysUser.setRoles(roles);
        // 查询菜单信息
        if (roles != null && roles.size() > 0) {
            List<Menu> menus = sysMenuService.listMenusByRoleIds(roles.stream().map(Role::getId).collect(Collectors.toList()));
            sysUser.setMenus(menus);
        }
        String str = sysUser.getUserName() + StringHelper.generateGUID() + System.currentTimeMillis();
        String accessToken = EncryptUtils.encodeBase64(str);
        sysUser.setToken(accessToken);
        redisCache.setCacheObject(str, sysUser, 30, TimeUnit.MINUTES);
        sysUser.setPassword(null);
        return Result.success(sysUser);
    }
}
